import { fileURLToPath, URL } from 'node:url'
import { resolve, dirname } from 'node:path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools'
import { createHtmlPlugin } from 'vite-plugin-html'
import compression from 'vite-plugin-compression'
// @ts-ignore
import eslint from 'vite-plugin-eslint'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { visualizer } from 'rollup-plugin-visualizer'
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'
import { lazyImport, VxeResolver } from 'vite-plugin-lazy-import'
import pkg from './package.json'

const { dependencies, devDependencies, name, version } = pkg
const __APP_INFO__ = {
	pkg: { dependencies, devDependencies, name, version },
	lastBuildTime: new Date().toLocaleString()
}

export default defineConfig(({ mode }) => {
	const isDEV = mode === 'development'
	const root = process.cwd()
	return {
		base: '/',
		root,
		define: {
			__APP_INFO__: JSON.stringify(__APP_INFO__),
			__VUE_PROD_DEVTOOLS__: JSON.stringify(isDEV),
			__DEV__: JSON.stringify(isDEV),
			__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'true'
		},
		plugins: [
			vue(),
			vueJsx(),
			vueDevTools(),
			VueI18nPlugin({
				module: 'petite-vue-i18n',
				include: resolve(dirname(fileURLToPath(import.meta.url)), './src/locales/lang/**')
			}),
			lazyImport({
				resolvers: [
					VxeResolver({
						libraryName: 'vxe-table'
					})
				]
			}),
			createHtmlPlugin({
				inject: {
					data: {
						title: 'admin',
						script: '<p>注入的😊</p>'
					}
				}
			}),
			eslint(),
			compression({
				verbose: true,
				disable: false,
				deleteOriginFile: false,
				threshold: 10240,
				algorithm: 'gzip',
				ext: '.gz'
			}),
			AutoImport({
				dts: true,
				imports: ['vue', 'vue-router', 'pinia', '@vueuse/core'],
				eslintrc: {
					enabled: true,
					filepath: './.eslintrc-auto-import.json',
					globalsPropValue: true
				},
				dirs: ['./src/composables']
			}),
			Components({
				dirs: ['./src/components'],
				dts: true
			}),
			visualizer({
				open: true, //注意这里要设置为true，否则无效
				gzipSize: true,
				brotliSize: true
			})
		],
		resolve: {
			alias: {
				'@': fileURLToPath(new URL('./src', import.meta.url))
			},
			extensions: ['.js', '.ts', '.jsx', '.tsx', '.json', '.vue', '.mjs']
		},
		build: {
			sourcemap: isDEV,
			outDir: 'dist',
			minify: 'esbuild', // esbuild打包速度最快，terser打包体积最小。
			assetsInlineLimit: 4000, // 小于该值 图片将打包成Base64
			reportCompressedSize: false, // 禁用 gzip 压缩大小报告，可略微减少打包时间
			// 规定触发警告的 chunk 大小
			chunkSizeWarningLimit: 2000,
			cssCodeSplit: true,
			rollupOptions: {
				output: {
					// js最小拆包
					manualChunks: id => {
						// 获取包名
						const getPackageName = (id: string) => {
							const parts = id.split('node_modules/')
							if (parts.length > 1) {
								const packagePart = parts[parts.length - 1]
								return packagePart.split('/')[0]
							}
							return null
						}

						const packageName = getPackageName(id)

						if (packageName) {
							// 大型库（> 500KB）单独分包
							const largeLibs = ['petite-vue-i18n', 'element-plus', 'vxe-table', '@vxe-ui', 'xe-utils']
							if (largeLibs.includes(packageName)) {
								return packageName
							}

							// Vue 生态系统
							if (['vue', 'vue-router', 'pinia'].includes(packageName)) {
								return 'vue-vendor'
							}

							// React 生态系统（如果混用）
							if (['react', 'react-dom', 'react-router'].includes(packageName)) {
								return 'react-vendor'
							}

							// 工具库
							if (['lodash', 'axios', 'dayjs'].includes(packageName)) {
								return 'utils'
							}

							// 其他第三方库
							return 'vendor'
						}

						// 项目代码按目录分包
						if (id.includes('/src/')) {
							if (id.includes('/src/views/')) {
								const viewPath = id.split('/src/views/')[1]
								const topLevelDir = viewPath.split('/')[0]
								return `views-${topLevelDir}`
							}

							if (id.includes('/src/components/')) {
								return 'components'
							}
						}
					},
					// 静态资源分类和包装
					chunkFileNames: 'assets/js/[name]-[hash].js',
					entryFileNames: 'assets/js/[name]-[hash].js',
					assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
				}
			}
		},
		optimizeDeps: {
			include: ['vue', 'vue-router', 'pinia', 'vxe-table']
		}
	}
})
